package dev.ece.suit.ui;

import java.awt.Adjustable;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import dev.ece.core.texture.Texture;
import dev.ece.suit.ui.event.MouseListenerAdapter;
import dev.ece.suit.ui.event.ScrollBarListener;
import dev.ece.util.lib.IntOffset;
import dev.ece.util.lib.IntRectangle;
import dev.ece.util.lib.Rectangle;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.obj.ObjectCount;

public class ScrollBar extends Component {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3868463206463565267L;

	/**
	 * 默认水平
	 */
	private int orientation = Adjustable.HORIZONTAL;
	
	private int value;
	
	private int min;
	
	private int max;
	
	private boolean pickup;
	
	private Vector2f pickupPosition = new Vector2f();
	
	private Vector2f pickupButtonPosition = new Vector2f();
	
	private Button handlerButton;
	
	private Collection<ScrollBarListener> scrollBarListeners = Collections.synchronizedList(new ArrayList<ScrollBarListener>());
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height) throws IOException {
		this(background, textureClipping, width, height, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, int orientation) throws IOException {
		this(background, textureClipping, width, height, orientation, null);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, int orientation, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping) throws IOException {
		this(background, textureClipping, width, height, centerClipping, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation) throws IOException {
		this(background, textureClipping, width, height, centerClipping, orientation, null);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping) throws IOException {
		this(background, textureClipping, width, height, centerClipping, null);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = centerClipping.isVertical() ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(String background, float width, float height, IntRectangle centerClipping) throws IOException {
		this(background, width, height, centerClipping, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(String background, float width, float height, IntRectangle centerClipping, int orientation) throws IOException {
		this(background, width, height, centerClipping, orientation, null);
	}
	
	public ScrollBar(String background, float width, float height, IntRectangle centerClipping, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(String background, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}

	public ScrollBar(String background, float width, float height, IntOffset centerClipping) throws IOException {
		this(background, width, height, centerClipping, null);
	}
	
	public ScrollBar(String background, float width, float height, IntOffset centerClipping, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, float width, float height, IntOffset centerClipping, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = centerClipping.isVertical() ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(String background, float width, float height) throws IOException {
		this(background, width, height, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(String background, float width, float height, int orientation) throws IOException {
		this(background, width, height, orientation, null);
	}
	
	public ScrollBar(String background, float width, float height, Button handlerButton) throws IOException {
		this(background, width, height, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(String background, float width, float height, int orientation, Button handlerButton) throws IOException {
		this(background, width, height, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(String background, float width, float height, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height) throws IOException {
		this(background, textureClipping, width, height, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, int orientation) throws IOException {
		this(background, textureClipping, width, height, orientation, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, int orientation, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping) throws IOException {
		this(background, textureClipping, width, height, centerClipping, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation) throws IOException {
		this(background, textureClipping, width, height, centerClipping, orientation, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping) throws IOException {
		this(background, textureClipping, width, height, centerClipping, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping, Button handlerButton) throws IOException {
		this(background, textureClipping, width, height, centerClipping, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, IntRectangle textureClipping, float width, float height, IntOffset centerClipping, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, textureClipping, width, height, centerClipping);
		this.orientation = centerClipping.isVertical() ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntRectangle centerClipping) throws IOException {
		this(background, width, height, centerClipping, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntRectangle centerClipping, int orientation) throws IOException {
		this(background, width, height, centerClipping, orientation, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntRectangle centerClipping, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntRectangle centerClipping, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height, centerClipping);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}

	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntOffset centerClipping) throws IOException {
		this(background, width, height, centerClipping, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntOffset centerClipping, Button handlerButton) throws IOException {
		this(background, width, height, centerClipping, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, IntOffset centerClipping, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height, centerClipping);
		this.orientation = centerClipping.isVertical() ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height) throws IOException {
		this(background, width, height, Adjustable.HORIZONTAL, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, int orientation) throws IOException {
		this(background, width, height, orientation, null);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, Button handlerButton) throws IOException {
		this(background, width, height, Adjustable.HORIZONTAL, handlerButton);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, int orientation, Button handlerButton) throws IOException {
		this(background, width, height, orientation, handlerButton, 0, 0, 100);
	}
	
	public ScrollBar(ObjectCount<Texture> background, float width, float height, int orientation, Button handlerButton, int value, int min, int max) throws IOException {
		super(background, width, height);
		if(orientation == Adjustable.HORIZONTAL && width <= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("width 必须大于 height");
		}
		if(orientation == Adjustable.VERTICAL && width >= height) {
			this.getUi().destroy();
			throw new IllegalArgumentException("height必须大于 width");
		}
		if(min >= max) {
			this.getUi().destroy();
			throw new IllegalArgumentException("max必须大于 min");
		}
		this.orientation = orientation == Adjustable.VERTICAL ? Adjustable.VERTICAL : Adjustable.HORIZONTAL;
		this.min = min;
		this.max = max;
		this.setValueValue(value);
		this.handlerButton = handlerButton == null ? this.createHandlerButton() : handlerButton;
		this.setupHandlerButton();
	}
	
	protected void setupHandlerButton() {
		this.add(getHandlerButton());
		this.setHandlerButtonPosition(this.getValue());
		getHandlerButton().addMouseListener(new MouseListenerAdapter() {

			@Override
			public void onMouseButtonDown(int button, float x, float y) {
				setPickup(true);
				pickupPosition.set(x, y);
				pickupButtonPosition.set(getHandlerButton().position.getX(), getHandlerButton().position.getY());
			}

			@Override
			public void onMouseButtonUp(int button, float x, float y) {
				setPickup(false);
			}
			
		});
	}
	
	protected void setHandlerButtonPosition(int value) {
		int vleft = value - getMin();
		int vlength = getMax() - getMin();
		Rectangle rect = handlerButtonMoveRectangle();
		if(getOrientation() == Adjustable.VERTICAL) {
			float length = rect.top - rect.bottom;
			float y = rect.top - vleft * length / vlength;
			getHandlerButton().position.setY(y);
		} else {
			float length = rect.right - rect.left;
			float x = vleft * length / vlength + rect.left;
			getHandlerButton().position.setX(x);
		}
	}
	
	public Rectangle handlerButtonMoveRectangle() {
		float hw = this.getWidth() / 2;
		float hh = this.getHeight() / 2;
		float bhw = getHandlerButton().getWidth() / 2;
		float bhh = getHandlerButton().getHeight() / 2;
		return new Rectangle(-hw + bhw, hh - bhh, hw - bhw, -hh + bhh);
	}
	
	@Override
	public Rectangle getViewRectangle() {
		return getRectangle();
	}

	@Override
	public boolean mouseMove(float x, float y) {
		if(this.isVisible()) {
			return this.onMouseMove(x, y);
		}
		return false;
	}

	@Override
	public boolean onMouseMove(float x, float y) {
		if(this.isPickup()) {
			Rectangle rect = handlerButtonMoveRectangle();
			float length = 0;
			float fvalue = 0;
			if(getOrientation() == Adjustable.VERTICAL) {
				length = rect.top - rect.bottom;
				float ry = pickupButtonPosition.getY() + y - pickupPosition.getY();
				getHandlerButton().position.setY(ry > rect.top ? rect.top : (ry < rect.bottom ? rect.bottom : ry));
				fvalue = rect.top - getHandlerButton().position.getY();
			} else {
				length = rect.right - rect.left;
				float rx = pickupButtonPosition.getX() + x - pickupPosition.getX();
				getHandlerButton().position.setX(rx < rect.left ? rect.left : (rx > rect.right ? rect.right : rx));
				fvalue = getHandlerButton().position.getX() - rect.left;
			}
			int vlength = getMax() - getMin();
			int value = (int) (fvalue * vlength / length + getMin());
			if(value != getValue()) {
				this.setValueValue(value); 
				this.triggerScrollBarListener();
			}
		}
		return false;
	}
	
	protected void triggerScrollBarListener() {
		for(ScrollBarListener listener: scrollBarListeners) {
			listener.onScroll(this, getValue(), getMin(), getMax());
		}
	}

	protected Button createHandlerButton() {
		float width = getOrientation() == Adjustable.VERTICAL ? this.getWidth() : this.getHeight();
		BufferedImage image = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);
		Graphics g = image.getGraphics();
		g.setColor(Color.GRAY);
		g.drawRoundRect(0, 0, image.getWidth(), image.getHeight(), 5, 5);
		g.fillRoundRect(0, 0, image.getWidth(), image.getHeight(), 5, 5);
		g.dispose();
		return new Button(createBackground(image), width, width);
	}

	protected Collection<ScrollBarListener> getScrollBarListeners() {
		return scrollBarListeners;
	}

	public void addScrollBarListener(ScrollBarListener scrollBarListener) {
		if(!containsScrollBarListener(scrollBarListener)) {
			getScrollBarListeners().add(scrollBarListener);
		}
	}
	
	public boolean containsScrollBarListener(ScrollBarListener scrollBarListener) {
		return getScrollBarListeners().contains(scrollBarListener);
	}
	
	public void removeScrollBarListener(ScrollBarListener scrollBarListener) {
		getScrollBarListeners().remove(scrollBarListener);
	}
	
	public int scrollBarListenersLength() {
		return getScrollBarListeners().size();
	}
	
	protected boolean isPickup() {
		return pickup;
	}

	protected void setPickup(boolean pickup) {
		this.pickup = pickup;
	}

	public Button getHandlerButton() {
		return handlerButton;
	}

	public int getOrientation() {
		return orientation;
	}

	protected void setValueValue(int value) {
		this.value = value > getMax() ? getMax() : (value < getMin() ? getMin() : value);
	}
	
	public void scroll(int value) {
		setValue(value);
		triggerScrollBarListener();
	}
	
	public void setValue(int value) {
		this.setValueValue(value);
		this.setHandlerButtonPosition(getValue());
	}
	
	public int getValue() {
		return value;
	}

	public int getMin() {
		return min;
	}

	public int getMax() {
		return max;
	}

	@Override
	public void clearup() {
		super.clearup();
		scrollBarListeners.clear();
	}
	
}
